﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Sharp7;
using S7.Net;
using WpfAGVSystem.DBModel;
using WpfAGVSystem.InterFace;
using WpfAGVSystem.Common;
using Prism.Mvvm;
using Microsoft.VisualBasic.ApplicationServices;
using System.Reflection;
using static WpfAGVSystem.Common.EnumDefinitions;
using System.Data;
using System.Runtime.CompilerServices;
using System.Data.SqlClient;
using Dommel;

namespace WpfAGVSystem.Model
{
    public class OvenModel: BindableBase
    {
        OvenModelData ovenModelData = new OvenModelData();
        private Action re;
        private Plc plc;
        private IDBInterface dBInterface;
        public static List<OvenModel> list_OvenModel = new List<OvenModel>(50);
        public int devid { get; set; }
        private bool Flag = false;
        public bool CloseFlag { get; set; } = false;
        private LogClass logClass;
        Type type = typeof(Oven_Entity);
        private Oven_Entity _oven_Entity;
        PropertyInfo[] Props;
        public int IsClose { get; set; }
        public OvenModel(IDBInterface _dBInterface, Oven_Entity oven_Entity) 
        {
            dBInterface = _dBInterface;
            plc = new Plc(CpuType.S71200,oven_Entity.Ip,0,1);
            devid = oven_Entity.Deviceid;
            list_OvenModel.Add(this);
            _oven_Entity = oven_Entity;
            logClass = new LogClass("OvenModel" + "---" + oven_Entity.Deviceid);
            Props = type.GetProperties();
            Task.Run(() => {
                //while (!Global.isClosing)
                //{
                //    var OvenCaches = _dBInterface.Where<OvenCache_Entity>(x => x.IsEnable == true && x.IsCReat == false && x.IsHave == true && x.OvenID==devid);
                //    if (OvenCaches!=null)
                //    {
                //        foreach (var item in OvenCaches)
                //        {
                //            try
                //            {
                //              var star= Convert.ToDateTime(item.UpdataTime);
                //              var timespae = DateTime.Now - star;
                //                if (timespae.Hours+timespae.Minutes/60 >= item.OvenTime)
                //                {

                //                    using (IDbConnection connection = new SqlConnection(ConfigHelper.DBcon))
                //                    {
                //                        connection.Open();
                //                        IDbTransaction dbTransaction = connection.BeginTransaction();
                //                        try
                //                        {
                //                            var Oventasktype = connection.FirstOrDefault<TaskType_Entity>(x => x.TaskType == oven_Entity.Unloading_Full, dbTransaction);
                //                            if (Oventasktype == null)
                //                            {
                //                                dbTransaction.Rollback();
                //                                return false;
                //                            }
                //                            var Full= connection.FirstOrDefault<FullCache_Entity>(x =>x.IsCreat==false && x.IsHave==false, dbTransaction);
                //                            var FullCachetasktype = connection.FirstOrDefault<TaskType_Entity>(x => x.TaskType == FullCache.Unwind_Full, dbTransaction);
                //                            if (FullCachetasktype == null)
                //                            {
                //                                dbTransaction.Rollback();
                //                                return false;
                //                            }

                //                            Task_Entity Oventask = new Task_Entity()
                //                            {
                //                                AreaType = Oven.PickAreaType,
                //                                Devid = Oven.Deviceid,
                //                                MacTaskState = 0,
                //                                PreStation = Oven.PreStation,
                //                                Station = Oven.Station,
                //                                BackStation = Oven.BackStation,
                //                                CreateTime = DateTime.Now.ToString(),
                //                                TagerFlow = Oven.Flow,
                //                                TaskType_TaskType = Oventasktype.TaskType,
                //                                Level = 2,
                //                                ManipulatorId = Oven.Manipulatorid,
                //                                OvenId = Oven.Deviceid,
                //                                OvenPostion = ovenpostion,
                //                            };
                //                            Task_Entity FullCachetask = new Task_Entity()
                //                            {
                //                                AreaType = FullCache.PutAreaType,
                //                                Devid = FullCache.Deviceid,
                //                                MacTaskState = 0,
                //                                PreStation = FullCache.PreStation,
                //                                Station = FullCache.Station,
                //                                BackStation = FullCache.BackStation,
                //                                CreateTime = DateTime.Now.ToString(),
                //                                TagerFlow = FullCache.Flow,
                //                                TaskType_TaskType = FullCachetasktype.TaskType,
                //                                FullBakeState = (int)Bakingstate.Baked,
                //                                Level = 2
                //                            };
                //                            FullCache.IsCreat = true;
                //                            connection.Update(FullCache, dbTransaction);
                //                            connection.Insert(Oventask, dbTransaction);
                //                            connection.Insert(FullCachetask, dbTransaction);

                //                            dbTransaction.Commit();
                //                        }
                //                        catch (Exception)
                //                        {

                //                            dbTransaction.Rollback();
                //                            return false;
                //                        }


                //                    }
                //                    return true;
                //                }
                              
                //            }
                //            catch (Exception)
                //            {

                //                continue;
                //            }
                //        }
                //    }
                  
                //}
            
            });
        }
        public void Close()
        {
            if (plc != null && plc.IsConnected)
            {
                plc.Close();
            }
        }
        public bool Put(int posion) 
        {
            try
            {

                plc.Write(DataType.DataBlock, 55, 0, (Int16)posion);
                plc.Write(DataType.DataBlock, 55, 2, (Int16)10);
                Task.Delay(2000).Wait();
                if (ovenModelData.DataRec[0]!=(Int16)posion || ovenModelData.DataRec[1]!=(Int16)10)
                {
                    //plc.Write(DataType.DataBlock, 710, 44, (Int16)posion);
                    //plc.Write(DataType.DataBlock, 710, 46, (Int16)1);
                    //Task.Delay(1000).Wait();
                    return false;
                }
                return true;
            }
            catch (Exception)
            {

                return false;
                // throw;
            }
        }
        public bool Get(int posion) 
        {
            try
            {

                plc.Write(DataType.DataBlock, 55, 0, (Int16)posion);
                plc.Write(DataType.DataBlock, 55, 2, (Int16)1);
                Task.Delay(2000).Wait();
                if (ovenModelData.DataRec[0] != (Int16)posion || ovenModelData.DataRec[1] != (Int16)1)
                {
                    //plc.Write(DataType.DataBlock, 710, 44, (Int16)posion);
                    //plc.Write(DataType.DataBlock, 710, 46, (Int16)1);
                    //Task.Delay(1000).Wait();
                    return false;
                }
                return true;
            }
            catch (Exception)
            {

                return false;
                // throw;
            }
        }

        public bool Con()
        {
            lock ("Con")
            {

                if (!plc.IsConnected)
                {
                    try
                    {
                        plc.Open();
                        CloseFlag = false;
                        Flag = true;
                        Read();
                        logClass.Push("连接PLC成功");
                        return true;
                    }
                    catch (Exception e)
                    {
                        Flag = false;

                        logClass.Push("连接失败");
                        logClass.PushEx(e);
                        return false;
                    }
                }
                logClass.Push("连接成功后再次连接");
                Flag = true;
                return true;
            }
        }
        public void Read()
        {
            Task.Run(() => {

                while (Flag)
                {

                    try
                    {
                       plc.ReadClass(ovenModelData, 55, 0);
                       // object a = Activator.CreateInstance(type);   //创建对象
                        //_oven_Entity.state1 
                        for (int i = 0; i < ovenModelData.DataSend.Length; i++)
                        {
                            var str = $"state{i + 1}";
                           var Prop= Props.FirstOrDefault(x => x.Name == str);
                            if (Prop != null)
                            {
                                if (ovenModelData.DataSend[i] == 1)
                                {
                                    Prop.SetValue(_oven_Entity, true);
                                }
                                else 
                                {
                                    Prop.SetValue(_oven_Entity, false);
                                }
                              
                            }
                           
                        }
                        int temp = 0;
                        for (int i = 0; i < ovenModelData.DataSendDoor.Length; i++)
                        {
                            temp += ovenModelData.DataSendDoor[i];
                        }
                        IsClose = temp;
                        _oven_Entity.IsOnline=true;
                        dBInterface.Update(_oven_Entity);
                     
                    }
                    catch (Exception e)
                    {
                        logClass.Push("plc通讯异常");
                        Flag = false;
                    }

                }
                re = new Action(RECon);
                re.Invoke();
                int c = 0;
            });
        }
        public void RECon()
        {
            if (!CloseFlag)
            {
                int k = 0;
                logClass.Push($"plc通讯异常后，自动重连,第{k}次");
                while (!CloseFlag)
                {
                    logClass.Push($"plc通讯异常后，自动重连,第{k++}次");
                    if (Con())
                    {
                        break;
                    }
                    Task.Delay(2000).Wait();
                }
            }

        }

        public class OvenModelData 
        {
            public Int16[] DataRec { get; set; } = new Int16[25];
            public Int16[] DataSend { get; set; } = new Int16[25];
            public Int16[] DataSendDoor { get; set; } = new Int16[25];
        }
    }
}
